home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / Mesa-1.2.1 / src-tk / tkwndws.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-05  |  28.2 KB  |  1,096 lines

  1. /*
  2.  * (c) Copyright 1993, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  * Permission to use, copy, modify, and distribute this software for
  5.  * any purpose and without fee is hereby granted, provided that the above
  6.  * copyright notice appear in all copies and that both the copyright notice
  7.  * and this permission notice appear in supporting documentation, and that
  8.  * the name of Silicon Graphics, Inc. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.
  11.  *
  12.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  16.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  21.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  *
  25.  * US Government Users Restricted Rights
  26.  * Use, duplication, or disclosure by the Government is subject to
  27.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29.  * clause at DFARS 252.227-7013 and/or in similar or successor
  30.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  31.  * Unpublished-- rights reserved under the copyright laws of the
  32.  * United States.  Contractor/manufacturer is Silicon Graphics,
  33.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  34.  *
  35.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  36.  */
  37.  
  38. // Mesa Tweaking by: Mark E. Peterson (markp@ic.mankato.mn.us)
  39.  
  40. #include <windows.h>
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include "tk.h"
  45. #include "gl\wmesa.h"
  46.  
  47. #define static
  48.  
  49. #if defined(__cplusplus) || defined(c_plusplus)
  50. #define class c_class
  51. #endif
  52.  
  53. #if DBG
  54. #define TKASSERT(x)                                     \
  55. if ( !(x) ) {                                           \
  56.     PrintMessage("%s(%d) Assertion failed %s\n",        \
  57.         __FILE__, __LINE__, #x);                        \
  58. }
  59. #else
  60. #define TKASSERT(x)
  61. #endif  /* DBG */
  62.  
  63. /******************************************************************************/
  64.  
  65. static struct _WINDOWINFO {
  66.     int x, y;
  67.     int width, height;
  68.     GLenum type;
  69.     GLenum dmPolicy;
  70.     int ipfd;
  71.     BOOL bDefPos;
  72. } windInfo = {
  73.     0, 0, 100, 100, TK_INDEX | TK_SINGLE, TK_MINIMUM_CRITERIA, 0, TRUE
  74. };
  75.  
  76.  
  77. static HWND     tkhwnd     = NULL;
  78. static HDC      tkhdc      = NULL;
  79. static HPALETTE tkhpalette = NULL;
  80. GLboolean tkPopupEnable = TRUE;
  81.  
  82. // Fixed palette support.
  83.  
  84. #define BLACK   PALETTERGB(0,0,0)
  85. #define WHITE   PALETTERGB(255,255,255)
  86. #define NUM_STATIC_COLORS   (COLOR_BTNHIGHLIGHT - COLOR_SCROLLBAR + 1)
  87.  
  88. static void (*ExposeFunc)(int, int)              = NULL;
  89. static void (*ReshapeFunc)(GLsizei, GLsizei)     = NULL;
  90. static void (*DisplayFunc)(void)                 = NULL;
  91. static GLenum (*KeyDownFunc)(int, GLenum)        = NULL;
  92. static GLenum (*MouseDownFunc)(int, int, GLenum) = NULL;
  93. static GLenum (*MouseUpFunc)(int, int, GLenum)   = NULL;
  94. static GLenum (*MouseMoveFunc)(int, int, GLenum) = NULL;
  95. static void (*IdleFunc)(void)                    = NULL;
  96.  
  97. static char     *lpszClassName = "tkLibWClass";
  98. static WCHAR    *lpszClassNameW = L"tkLibWClass";
  99.  
  100. long FAR PASCAL _export tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam);
  101. static unsigned char ComponentFromIndex(int i, int nbits, int shift );
  102. static void PrintMessage( const char *Format, ... );
  103. //static PALETTEENTRY *FillRgbPaletteEntries( PIXELFORMATDESCRIPTOR *Pfd, PALETTEENTRY *Entries, UINT Count );
  104. static HPALETTE CreateCIPalette( HDC Dc );
  105. static HPALETTE CreateRGBPalette( HDC hdc );
  106. static void DestroyThisWindow( HWND Window );
  107. static void CleanUp( void );
  108. static void DelayPaletteRealization( void );
  109. static long RealizePaletteNow( HDC Dc, HPALETTE Palette);
  110. static void ForceRedraw( HWND Window );
  111. static void *AllocateMemory( size_t Size );
  112. static void *AllocateZeroedMemory( size_t Size );
  113. static void FreeMemory( void *Chunk );
  114.  
  115. /*
  116.  *  Prototypes for the debugging functions go here
  117.  */
  118.  
  119. #define DBGFUNC 0
  120. #if DBGFUNC
  121.  
  122. static void DbgPrintf( const char *Format, ... );
  123. static void pwi( void );
  124. static void pwr(RECT *pr);
  125. //static void ShowPixelFormat(HDC hdc);
  126.  
  127. #endif
  128. #define NCOLORS 17
  129. float tkRGBMap[NCOLORS][3] = {
  130.     {0,0,0},
  131.     {0,0,0},
  132.     {0,0,0},
  133.     {0,0,0},
  134.     {0,0,0},
  135.     {0,0,0},
  136.     {0,0,0},
  137.     {0,0,0},
  138.     {0,0,0},
  139.     {0,0,0},
  140.     {1,0,0},
  141.     {0,1,0},
  142.     {1,1,0},
  143.     {0,0,1},
  144.     {1,0,1},
  145.     {0,1,1},
  146.     {1,1,1}
  147. };
  148.  
  149.  
  150. /***************************************************************
  151.  *                                                             *
  152.  *  Exported Functions go here                                 *
  153.  *                                                             *
  154.  ***************************************************************/
  155.  
  156. void tkErrorPopups(GLboolean bEnable)
  157. {
  158.     tkPopupEnable = bEnable;
  159. }
  160.  
  161. void tkCloseWindow(void)
  162. {
  163.     DestroyThisWindow(tkhwnd);
  164.     /* if (w.cMain) {
  165.        XMesaDestroyContext(w.cMain);
  166.     }*/
  167.     WMesaDestroyContext(NULL);
  168. }
  169.  
  170.  
  171. void tkExec(void)
  172. {
  173.     MSG Message;
  174.  
  175.     /*
  176.      *  WM_SIZE gets delivered before we get here!
  177.      */
  178.  
  179.     if (ReshapeFunc)
  180.     {
  181.         RECT ClientRect;
  182.  
  183.         GetClientRect(tkhwnd, &ClientRect);
  184.         (*ReshapeFunc)(ClientRect.right, ClientRect.bottom);
  185.     }
  186.  
  187.     while (GL_TRUE)
  188.     {
  189.         /*
  190.          *  Process all pending messages
  191.          */
  192.  
  193.         while (PeekMessage(&Message, NULL, 0, 0, PM_NOREMOVE) == TRUE)
  194.         {
  195.             if (GetMessage(&Message, NULL, 0, 0) )
  196.             {
  197.                 TranslateMessage(&Message);
  198.                 DispatchMessage(&Message);
  199.             }
  200.             else
  201.             {
  202.                 /*
  203.                  *  Nothing else to do here, just return
  204.                  */
  205.  
  206.                 return;
  207.             }
  208.         }
  209.  
  210.         /*
  211.          *  If an idle function was defined, call it
  212.          */
  213.  
  214.         if (IdleFunc)
  215.         {
  216.             (*IdleFunc)();
  217.         }
  218.     }
  219. }
  220.  
  221. void tkExposeFunc(void (*Func)(int, int))
  222. {
  223.     ExposeFunc = Func;
  224. }
  225.  
  226. void tkReshapeFunc(void (*Func)(GLsizei, GLsizei))
  227. {
  228.     ReshapeFunc = Func;
  229. }
  230.  
  231. void tkDisplayFunc(void (*Func)(void))
  232. {
  233.     DisplayFunc = Func;
  234. }
  235.  
  236. void tkKeyDownFunc(GLenum (*Func)(int, GLenum))
  237. {
  238.     KeyDownFunc = Func;
  239. }
  240.  
  241. void tkMouseDownFunc(GLenum (*Func)(int, int, GLenum))
  242. {
  243.     MouseDownFunc = Func;
  244. }
  245.  
  246. void tkMouseUpFunc(GLenum (*Func)(int, int, GLenum))
  247. {
  248.     MouseUpFunc = Func;
  249. }
  250.  
  251. void tkMouseMoveFunc(GLenum (*Func)(int, int, GLenum))
  252. {
  253.     MouseMoveFunc = Func;
  254. }
  255.  
  256. void tkIdleFunc(void (*Func)(void))
  257. {
  258.     IdleFunc = Func;
  259. }
  260.  
  261. void tkInitPosition(int x, int y, int width, int height)
  262. {
  263.     if (x == CW_USEDEFAULT)
  264.     {
  265.         x = 0;
  266.         y = 0;
  267.         windInfo.bDefPos = TRUE;
  268.     }
  269.     else
  270.         windInfo.bDefPos = FALSE;
  271.  
  272.     windInfo.x = x + GetSystemMetrics(SM_CXFRAME);
  273.     windInfo.y = y + GetSystemMetrics(SM_CYCAPTION)
  274.                  - GetSystemMetrics(SM_CYBORDER)
  275.                  + GetSystemMetrics(SM_CYFRAME);
  276.     windInfo.width = width;
  277.     windInfo.height = height;
  278. }
  279.  
  280. void tkInitDisplayMode(GLenum type)
  281. {
  282.     windInfo.type = type;
  283. }
  284.  
  285. void tkInitDisplayModePolicy(GLenum type)
  286. {
  287.     windInfo.dmPolicy = type;
  288. }
  289.  
  290. GLenum tkInitDisplayModeID(GLint ipfd)
  291. {
  292.     windInfo.ipfd = ipfd;
  293.     return GL_TRUE;
  294. }
  295.  
  296. GLenum tkInitWindowAW(char *title, BOOL bUnicode)
  297. {
  298.     WMesaContext Cur;
  299.     WNDCLASS wndclass;
  300.     RECT     WinRect;
  301.     HANDLE   hInstance;
  302.     ATOM     aRegister;
  303.     GLenum   Result = GL_FALSE,RGB_Flag=GL_TRUE,DB_Flag=GL_FALSE;
  304.  
  305.     hInstance = GetModuleHandle(NULL);
  306.  
  307.     // Must not define CS_CS_PARENTDC style.
  308.     wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  309.     wndclass.lpfnWndProc   = (WNDPROC)tkWndProc;
  310.     wndclass.cbClsExtra    = 0;
  311.     wndclass.cbWndExtra    = 0;
  312.     wndclass.hInstance     = hInstance;
  313.     wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  314.     wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  315.     wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
  316.     wndclass.lpszMenuName  = NULL;
  317.  
  318.     if (bUnicode)
  319.         wndclass.lpszClassName = (LPCSTR)lpszClassNameW;
  320.     else
  321.         wndclass.lpszClassName = (LPCSTR)lpszClassName;
  322.  
  323.     if (bUnicode)
  324.     {
  325.         aRegister = RegisterClassW((CONST WNDCLASSW *)&wndclass);
  326.     }
  327.     else
  328.     {
  329.         aRegister = RegisterClass(&wndclass);
  330.     }
  331.  
  332.  
  333.     /*
  334.      *  If the window failed to register, then there's no
  335.      *  need to continue further.
  336.      */
  337.  
  338.     if(0 == aRegister)
  339.     {
  340.         PrintMessage("Failed to register window class\n");
  341.         return(Result);
  342.     }
  343.  
  344.  
  345.     /*
  346.      *  Make window large enough to hold a client area as large as windInfo
  347.      */
  348.  
  349.     WinRect.left   = windInfo.x;
  350.     WinRect.right  = windInfo.x + windInfo.width;
  351.     WinRect.top    = windInfo.y;
  352.     WinRect.bottom = windInfo.y + windInfo.height;
  353.  
  354.     AdjustWindowRect(&WinRect, WS_OVERLAPPEDWINDOW, FALSE);
  355.  
  356.     /*
  357.      *  Must use WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles.
  358.      */
  359.  
  360.     if (bUnicode)
  361.     {
  362.         tkhwnd = CreateWindowW(
  363.                     (LPCWSTR)lpszClassNameW,
  364.                     (LPCWSTR)title,
  365.                     WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  366.                     (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.left,
  367.                     (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.top,
  368.                     WinRect.right - WinRect.left,
  369.                     WinRect.bottom - WinRect.top,
  370.                     NULL,
  371.                     NULL,
  372.                     hInstance,
  373.                     NULL);
  374.     }
  375.     else
  376.     {
  377.         tkhwnd = CreateWindow(
  378.                     lpszClassName,
  379.                     title,
  380.                     WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  381.                     (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.left,
  382.                     (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.top,
  383.                     WinRect.right - WinRect.left,
  384.                     WinRect.bottom - WinRect.top,
  385.                     NULL,
  386.                     NULL,
  387.                     hInstance,
  388.                     NULL);
  389.     }
  390.  
  391.     if ( NULL != tkhwnd )
  392.     {
  393.         // If default window positioning used, find out window position and fix
  394.         // up the windInfo position info.
  395.  
  396.         if (windInfo.bDefPos)
  397.         {
  398.             GetWindowRect(tkhwnd, &WinRect);
  399.             windInfo.x = WinRect.left + GetSystemMetrics(SM_CXFRAME);
  400.             windInfo.y = WinRect.top  + GetSystemMetrics(SM_CYCAPTION)
  401.                          - GetSystemMetrics(SM_CYBORDER)
  402.                          + GetSystemMetrics(SM_CYFRAME);
  403.         }
  404.  
  405.         tkhdc = GetDC(tkhwnd);
  406.  
  407.         if ( NULL != tkhdc )
  408.             ShowWindow(tkhwnd, SW_SHOWDEFAULT);
  409.         else
  410.             PrintMessage("Could not get an HDC for window 0x%08lX\n", tkhwnd );
  411.     }
  412.     else
  413.         PrintMessage("create window failed\n");
  414.     if (windInfo.type & TK_INDEX)
  415.     {
  416.       RGB_Flag=GL_FALSE;
  417.       tkSetRGBMap(NCOLORS,(float *) tkRGBMap);
  418.     }
  419.     if (windInfo.type & TK_DOUBLE)
  420.       DB_Flag=GL_TRUE;
  421.     Cur=WMesaCreateContext(tkhwnd,tkhpalette,RGB_Flag,DB_Flag);
  422.     WMesaMakeCurrent(Cur);
  423.     return GL_TRUE;
  424. }
  425.  
  426. // Initialize a window, create a rendering context for that window
  427. GLenum tkInitWindow(char *title)
  428. {
  429.     TKASSERT( NULL==tkhwnd      );
  430.     TKASSERT( NULL==tkhdc       );
  431.     TKASSERT( NULL==tkhrc       );
  432.     TKASSERT( NULL==tkhpalette  );
  433.  
  434.     return tkInitWindowAW(title, FALSE);
  435. }
  436.  
  437.  
  438. /******************************************************************************/
  439.  
  440. /*
  441.  * You cannot just call DestroyWindow() here.  The programs do not expect
  442.  * tkQuit() to return;  DestroyWindow() just sends a WM_DESTROY message
  443.  */
  444.  
  445. void tkQuit(void)
  446. {
  447.     DestroyThisWindow(tkhwnd);
  448.     ExitProcess(0);
  449. }
  450.  
  451. /******************************************************************************/
  452.  
  453. void tkSetOneColor(int index, float r, float g, float b)
  454. {
  455.     PALETTEENTRY PalEntry;
  456.     HPALETTE Palette;
  457.     if ( NULL != (Palette = CreateCIPalette( tkhdc )) )
  458.     {
  459.         PalEntry.peRed   = (BYTE)(r*(float)255.0 + (float)0.5);
  460.         PalEntry.peGreen = (BYTE)(g*(float)255.0 + (float)0.5);
  461.         PalEntry.peBlue  = (BYTE)(b*(float)255.0 + (float)0.5);
  462.         PalEntry.peFlags = 0;
  463.         SetPaletteEntries( Palette, index, 1, &PalEntry);
  464.         DelayPaletteRealization();
  465.     }
  466. }
  467.  
  468. void tkSetFogRamp(int density, int startIndex)
  469. {
  470.     HPALETTE CurrentPal;
  471.     PALETTEENTRY *pPalEntry;
  472.     UINT n, i, j, k, intensity, fogValues, colorValues;
  473.  
  474.     if ( NULL != (CurrentPal = CreateCIPalette(tkhdc)) )
  475.     {
  476.         n = GetPaletteEntries( CurrentPal, 0, 0, NULL );
  477.  
  478.         pPalEntry = AllocateMemory( n * sizeof(PALETTEENTRY) );
  479.  
  480.         if ( NULL != pPalEntry)
  481.         {
  482.             fogValues = 1 << density;
  483.             colorValues = 1 << startIndex;
  484.             for (i = 0; i < colorValues; i++) {
  485.                 for (j = 0; j < fogValues; j++) {
  486.                     k = i * fogValues + j;
  487.  
  488.                     intensity = i * fogValues + j * colorValues;
  489.                     //mf: not sure what they're trying to do here
  490.                     //intensity = (intensity << 8) | intensity; ???
  491.  
  492.                 // This is a workaround for a GDI palette "feature".  If any of
  493.                 // the static colors are repeated in the palette, those colors
  494.                 // will map to the first occurance.  So, for our case where there
  495.                 // are only two static colors (black and white), if a white
  496.                 // color appears anywhere in the palette other than in the last
  497.                 // entry, the static white will remap to the first white.  This
  498.                 // destroys the nice one-to-one mapping we are trying to achieve.
  499.                 //
  500.                 // There are two ways to workaround this.  The first is to
  501.                 // simply not allow a pure white anywhere but in the last entry.
  502.                 // Such requests are replaced with an attenuated white of
  503.                 // (0xFE, 0xFE, 0xFE).
  504.                 //
  505.                 // The other way is to mark these extra whites with PC_RESERVED
  506.                 // which will cause GDI to skip these entries when mapping colors.
  507.                 // This way the app gets the actual colors requested, but can
  508.                 // have side effects on other apps.
  509.                 //
  510.                 // Both solutions are included below.  The PC_RESERVED solution is
  511.                 // the one currently enabled.  It may have side effects, but taking
  512.                 // over the static colors as we are is a really big side effect that
  513.                 // should swamp out the effects of using PC_RESERVED.
  514.                 if (intensity > 0xFF)
  515.                   intensity = 0xFF;
  516.                 pPalEntry[k].peRed =pPalEntry[k].peGreen = pPalEntry[k].peBlue = (BYTE) intensity;
  517.                 pPalEntry[k].peFlags = 0;
  518.  
  519.                 }
  520.             }
  521.  
  522.             SetPaletteEntries(CurrentPal, 0, n, pPalEntry);
  523.             FreeMemory( pPalEntry );
  524.  
  525.             DelayPaletteRealization();
  526.         }
  527.     }
  528. }
  529.  
  530. void tkSetGreyRamp(void)
  531. {
  532.     HPALETTE CurrentPal;
  533.     PALETTEENTRY *Entries;
  534.     UINT Count, i;
  535.     float intensity;
  536.  
  537.     if ( NULL != (CurrentPal = CreateCIPalette( tkhdc )) )
  538.     {
  539.         Count   = GetPaletteEntries( CurrentPal, 0, 0, NULL );
  540.         Entries = AllocateMemory( Count * sizeof(PALETTEENTRY) );
  541.  
  542.         if ( NULL != Entries )
  543.         {
  544.             for (i = 0; i < Count; i++)
  545.             {
  546.                 intensity = (float)(((double)i / (double)(Count-1)) * (double)255.0 + (double)0.5);
  547.                 Entries[i].peRed =
  548.                 Entries[i].peGreen =
  549.                 Entries[i].peBlue = (BYTE) intensity;
  550.                 Entries[i].peFlags = 0;
  551.             }
  552.             SetPaletteEntries( CurrentPal, 0, Count, Entries );
  553.             FreeMemory( Entries );
  554.  
  555.             DelayPaletteRealization();
  556.         }
  557.     }
  558. }
  559.  
  560. void tkSetRGBMap( int Size, float *Values )
  561. {
  562.     HPALETTE CurrentPal;
  563.     int i;
  564.     if ( NULL != (CurrentPal = CreateCIPalette( tkhdc )) )
  565.     {
  566.       for (i=0; i<Size; i++)
  567.         tkSetOneColor(i,Values[i*3],Values[i*3+1],Values[i*3+2]);
  568.     }
  569. }
  570.  
  571. /******************************************************************************/
  572.  
  573. void tkSwapBuffers(void)
  574. {
  575.   WMesaSwapBuffers();
  576. }
  577.  
  578. /******************************************************************************/
  579.  
  580. GLint tkGetColorMapSize(void)
  581. {
  582.     CreateCIPalette( tkhdc );
  583.  
  584.     if ( NULL == tkhpalette )
  585.         return( 0 );
  586.  
  587.     return( GetPaletteEntries( tkhpalette, 0, 0, NULL ) );
  588. }
  589.  
  590. void tkGetMouseLoc(int *x, int *y)
  591. {
  592.     POINT Point;
  593.  
  594.     *x = 0;
  595.     *y = 0;
  596.  
  597.     GetCursorPos(&Point);
  598.  
  599.     /*
  600.      *  GetCursorPos returns screen coordinates,
  601.      *  we want window coordinates
  602.      */
  603.  
  604.     *x = Point.x - windInfo.x;
  605.     *y = Point.y - windInfo.y;
  606. }
  607.  
  608. HWND tkGetHWND(void)
  609. {
  610.     return tkhwnd;
  611. }
  612.  
  613. HDC tkGetHDC(void)
  614. {
  615.     return tkhdc;
  616. }
  617. GLenum tkGetDisplayModePolicy(void)
  618. {
  619.     return windInfo.dmPolicy;
  620. }
  621.  
  622. GLint tkGetDisplayModeID(void)
  623. {
  624.     return windInfo.ipfd;
  625. }
  626.  
  627. GLenum tkGetDisplayMode(void)
  628. {
  629.     return windInfo.type;
  630. }
  631.  
  632.  
  633. /***********************************************************************
  634.  *                                                                     *
  635.  *  The Following functions are for our own use only. (ie static)      *
  636.  *                                                                     *
  637.  ***********************************************************************/
  638.  
  639. long FAR PASCAL _export
  640. tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam)
  641. {
  642.     int key;
  643.     PAINTSTRUCT paint;
  644.     HDC hdc;
  645.  
  646.     switch (message)
  647.     {
  648.  
  649.     case WM_USER:
  650.  
  651.         if ( RealizePaletteNow( tkhdc, tkhpalette) > 0 )
  652.             ForceRedraw( hWnd );
  653.         return(0);
  654.  
  655.     case WM_SIZE:
  656.         windInfo.width  = LOWORD(lParam);
  657.         windInfo.height = HIWORD(lParam);
  658.  
  659.         if (ReshapeFunc)
  660.         {
  661.             (*ReshapeFunc)(windInfo.width, windInfo.height);
  662.  
  663.             ForceRedraw( hWnd );
  664.         }
  665.         return (0);
  666.  
  667.     case WM_MOVE:
  668.         windInfo.x = LOWORD(lParam);
  669.         windInfo.y = HIWORD(lParam);
  670.         return (0);
  671.  
  672.     case WM_PAINT:
  673.  
  674.         /*
  675.          *  Validate the region even if there are no DisplayFunc.
  676.          *  Otherwise, USER will not stop sending WM_PAINT messages.
  677.          */
  678.  
  679.         hdc = BeginPaint(tkhwnd, &paint);
  680.  
  681.         if (DisplayFunc)
  682.         {
  683.             (*DisplayFunc)();
  684.         }
  685.  
  686.         EndPaint(tkhwnd, &paint);
  687.         return (0);
  688.  
  689.     case WM_PALETTECHANGED:
  690.         if ( hWnd != (HWND) wParam )
  691.           RealizePaletteNow(tkhdc,tkhpalette);
  692.         return (0);
  693.     case WM_QUERYNEWPALETTE:
  694.  
  695.     // In the foreground!  Let RealizePaletteNow do the work--
  696.     // if management of the static system color usage is needed,
  697.     // RealizePaletteNow will take care of it.
  698.  
  699.         if ( NULL != tkhpalette )
  700.         {
  701.             if ( RealizePaletteNow(tkhdc, tkhpalette) > 0 )
  702.                 ForceRedraw( hWnd );
  703.  
  704.             return (1);
  705.         }
  706.  
  707.         return (0);
  708.  
  709.     case WM_ACTIVATE:
  710.  
  711.     // If the window is going inactive, the palette must be realized to
  712.     // the background.  Cannot depend on WM_PALETTECHANGED to be sent since
  713.     // the window that comes to the foreground may or may not be palette
  714.     // managed.
  715.  
  716.         if ( LOWORD(wParam) == WA_INACTIVE )
  717.         {
  718.             if ( NULL != tkhpalette )
  719.             {
  720.             // Realize as a background palette.  Need to call
  721.             // RealizePaletteNow rather than RealizePalette directly to
  722.             // because it may be necessary to release usage of the static
  723.             // system colors.
  724.  
  725.                 if ( RealizePaletteNow( tkhdc, tkhpalette) > 0 )
  726.                     ForceRedraw( hWnd );
  727.             }
  728.         }
  729.  
  730.     // Allow DefWindowProc() to finish the default processing (which includes
  731.     // changing the keyboard focus).
  732.  
  733.         break;
  734.  
  735.     case WM_MOUSEMOVE:
  736.  
  737.         if (MouseMoveFunc)
  738.         {
  739.             GLenum mask;
  740.  
  741.             mask = 0;
  742.             if (wParam & MK_LBUTTON) {
  743.                 mask |= TK_LEFTBUTTON;
  744.             }
  745.             if (wParam & MK_MBUTTON) {
  746.                 mask |= TK_MIDDLEBUTTON;
  747.             }
  748.             if (wParam & MK_RBUTTON) {
  749.                 mask |= TK_RIGHTBUTTON;
  750.             }
  751.  
  752.             if ((*MouseMoveFunc)( LOWORD(lParam), HIWORD(lParam), mask ))
  753.             {
  754.                 ForceRedraw( hWnd );
  755.             }
  756.         }
  757.         return (0);
  758.  
  759.     case WM_LBUTTONDOWN:
  760.  
  761.         SetCapture(hWnd);
  762.  
  763.         if (MouseDownFunc)
  764.         {
  765.             if ( (*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  766.                  TK_LEFTBUTTON) )
  767.             {
  768.                 ForceRedraw( hWnd );
  769.             }
  770.         }
  771.         return (0);
  772.  
  773.     case WM_LBUTTONUP:
  774.  
  775.         ReleaseCapture();
  776.  
  777.         if (MouseUpFunc)
  778.         {
  779.             if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam), TK_LEFTBUTTON))
  780.             {
  781.                 ForceRedraw( hWnd );
  782.             }
  783.         }
  784.         return (0);
  785.  
  786.     case WM_MBUTTONDOWN:
  787.  
  788.         SetCapture(hWnd);
  789.  
  790.         if (MouseDownFunc)
  791.         {
  792.             if ((*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  793.                     TK_MIDDLEBUTTON))
  794.             {
  795.                 ForceRedraw( hWnd );
  796.             }
  797.         }
  798.         return (0);
  799.  
  800.     case WM_MBUTTONUP:
  801.  
  802.         ReleaseCapture();
  803.  
  804.         if (MouseUpFunc)
  805.         {
  806.             if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
  807.                 TK_MIDDLEBUTTON))
  808.             {
  809.                 ForceRedraw( hWnd );
  810.             }
  811.         }
  812.         return (0);
  813.  
  814.     case WM_RBUTTONDOWN:
  815.  
  816.         SetCapture(hWnd);
  817.  
  818.         if (MouseDownFunc)
  819.         {
  820.             if ((*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  821.                 TK_RIGHTBUTTON))
  822.             {
  823.                 ForceRedraw( hWnd );
  824.             }
  825.         }
  826.         return (0);
  827.  
  828.     case WM_RBUTTONUP:
  829.  
  830.         ReleaseCapture();
  831.  
  832.         if (MouseUpFunc)
  833.         {
  834.             if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
  835.                 TK_RIGHTBUTTON))
  836.             {
  837.                 ForceRedraw( hWnd );
  838.             }
  839.         }
  840.         return (0);
  841.  
  842.     case WM_KEYDOWN:
  843.         switch (wParam) {
  844.         case VK_SPACE:          key = TK_SPACE;         break;
  845.         case VK_RETURN:         key = TK_RETURN;        break;
  846.         case VK_ESCAPE:         key = TK_ESCAPE;        break;
  847.         case VK_LEFT:           key = TK_LEFT;          break;
  848.         case VK_UP:             key = TK_UP;            break;
  849.         case VK_RIGHT:          key = TK_RIGHT;         break;
  850.         case VK_DOWN:           key = TK_DOWN;          break;
  851.         default:                key = GL_FALSE;         break;
  852.         }
  853.  
  854.         if (key && KeyDownFunc)
  855.         {
  856.             GLenum mask;
  857.  
  858.             mask = 0;
  859.             if (GetKeyState(VK_CONTROL)) {
  860.                 mask |= TK_CONTROL;
  861.             }
  862.  
  863.             if (GetKeyState(VK_SHIFT)) {
  864.  
  865.                 mask |= TK_SHIFT;
  866.             }
  867.  
  868.             if ( (*KeyDownFunc)(key, mask) )
  869.             {
  870.                 ForceRedraw( hWnd );
  871.             }
  872.         }
  873.         return (0);
  874.  
  875.     case WM_CHAR:
  876.         if (('0' <= wParam && wParam <= '9') ||
  877.             ('a' <= wParam && wParam <= 'z') ||
  878.             ('A' <= wParam && wParam <= 'Z')) {
  879.  
  880.             key = wParam;
  881.         } else {
  882.             key = GL_FALSE;
  883.         }
  884.  
  885.         if (key && KeyDownFunc) {
  886.             GLenum mask;
  887.  
  888.             mask = 0;
  889.  
  890.             if (GetKeyState(VK_CONTROL)) {
  891.                 mask |= TK_CONTROL;
  892.             }
  893.  
  894.             if (GetKeyState(VK_SHIFT)) {
  895.                 mask |= TK_SHIFT;
  896.             }
  897.  
  898.             if ( (*KeyDownFunc)(key, mask) )
  899.             {
  900.                 ForceRedraw( hWnd );
  901.             }
  902.         }
  903.         return (0);
  904.  
  905.     case WM_CLOSE:
  906.         DestroyWindow(tkhwnd);
  907.         return(0);
  908.  
  909.     case WM_DESTROY:
  910.         CleanUp();
  911.         PostQuitMessage(TRUE);
  912.         return 0;
  913.     }
  914.     return(DefWindowProc( hWnd, message, wParam, lParam));
  915. }
  916. static HPALETTE CreateCIPalette( HDC Dc )
  917. {
  918.     LOGPALETTE *LogicalPalette;
  919.     HPALETTE StockPalette;
  920.     UINT PaletteSize, StockPaletteSize, EntriesToCopy;
  921.  
  922.     if ( (Dc != NULL) && (NULL == tkhpalette) )
  923.     {
  924.                 PaletteSize = 256; //(Pfd.cColorBits >= 8) ? 256 : (1 << Pfd.cColorBits);
  925.  
  926.                 LogicalPalette = AllocateZeroedMemory( sizeof(LOGPALETTE) +
  927.                                         (PaletteSize * sizeof(PALETTEENTRY)) );
  928.  
  929.                 if ( NULL != LogicalPalette )
  930.                 {
  931.                     LogicalPalette->palVersion    = 0x300;
  932.                     LogicalPalette->palNumEntries = PaletteSize;
  933.  
  934.                     StockPalette     = GetStockObject(DEFAULT_PALETTE);
  935.                     StockPaletteSize = GetPaletteEntries( StockPalette, 0, 0, NULL );
  936.  
  937.                     /*
  938.                      *  start by copying default palette into new one
  939.                      */
  940.  
  941.                     EntriesToCopy = StockPaletteSize < PaletteSize ?
  942.                                         StockPaletteSize : PaletteSize;
  943.  
  944.                     GetPaletteEntries( StockPalette, 0, EntriesToCopy,
  945.                                         LogicalPalette->palPalEntry );
  946.  
  947.                     /*
  948.                      *  If we are taking possession of the system colors,
  949.                      *  must guarantee that 0 and 255 are black and white
  950.                      *  (respectively).
  951.                      */
  952.  
  953.                     tkhpalette = CreatePalette(LogicalPalette);
  954.  
  955.                     FreeMemory(LogicalPalette);
  956.  
  957.                     RealizePaletteNow( Dc, tkhpalette);
  958.                 }
  959.             }
  960.     return( tkhpalette );
  961. }
  962. static void
  963. PrintMessage( const char *Format, ... )
  964. {
  965.     va_list ArgList;
  966.     char Buffer[256];
  967.  
  968.     va_start(ArgList, Format);
  969.     vsprintf(Buffer, Format, ArgList);
  970.     va_end(ArgList);
  971.  
  972.     MessageBox(GetFocus(), Buffer, "Error", MB_OK);
  973. }
  974.  
  975. static void
  976. DelayPaletteRealization( void )
  977. {
  978.     MSG Message;
  979.  
  980.     TKASSERT(NULL!=tkhwnd);
  981.  
  982.     /*
  983.      *  Add a WM_USER message to the queue, if there isn't one there already.
  984.      */
  985.  
  986.     if (!PeekMessage(&Message, tkhwnd, WM_USER, WM_USER, PM_NOREMOVE) )
  987.     {
  988.         PostMessage( tkhwnd, WM_USER, 0, 0);
  989.     }
  990. }
  991.  
  992. /******************************Public*Routine******************************\
  993. * RealizePaletteNow
  994. *
  995. * Select the given palette in background or foreground mode (as specified
  996. * by the bForceBackground flag), and realize the palette.
  997. *
  998. * If static system color usage is set, the system colors are replaced.
  999. *
  1000. * History:
  1001. *  26-Apr-1994 -by- Gilman Wong [gilmanw]
  1002. * Wrote it.
  1003. \**************************************************************************/
  1004.  
  1005. static long RealizePaletteNow( HDC Dc, HPALETTE Palette)
  1006. {
  1007.     long Result = -1;
  1008.     TKASSERT( NULL!=Dc      );
  1009.     TKASSERT( NULL!=Palette );
  1010.     if ( NULL != SelectPalette( Dc, Palette, FALSE ) )
  1011.     {
  1012.       Result = RealizePalette( Dc );
  1013.       WMesaPaletteChange(Palette);
  1014.     }
  1015.     return( Result );
  1016. }
  1017.  
  1018. static void
  1019. ForceRedraw( HWND Window )
  1020. {
  1021.     MSG Message;
  1022.  
  1023.     if (!PeekMessage(&Message, Window, WM_PAINT, WM_PAINT, PM_NOREMOVE) )
  1024.     {
  1025.         InvalidateRect( Window, NULL, FALSE );
  1026.     }
  1027. }
  1028. static void
  1029. DestroyThisWindow( HWND Window )
  1030. {
  1031.     if ( NULL != Window )
  1032.     {
  1033.         DestroyWindow( Window );
  1034.     }
  1035. }
  1036.  
  1037. /*
  1038.  *  This Should be called in response to a WM_DESTROY message
  1039.  */
  1040.  
  1041. static void
  1042. CleanUp( void )
  1043. {
  1044.     HPALETTE hStock;
  1045.  
  1046. // Cleanup the palette.
  1047.  
  1048.     if ( NULL != tkhpalette )
  1049.     {
  1050.     // If static system color usage is set, restore the system colors.
  1051.  
  1052.         if ((hStock = GetStockObject( DEFAULT_PALETTE ))!=NULL)
  1053.           SelectPalette( tkhdc, hStock, FALSE );
  1054.         DeleteObject( tkhpalette );
  1055.     }
  1056.  
  1057. // Cleanup the DC.
  1058.  
  1059.     if ( NULL != tkhdc )
  1060.         ReleaseDC( tkhwnd, tkhdc );
  1061. // Be really nice and reset global values.
  1062.     tkhwnd        = NULL;
  1063.     tkhdc         = NULL;
  1064.     tkhpalette    = NULL;
  1065.  
  1066.     ExposeFunc    = NULL;
  1067.     ReshapeFunc   = NULL;
  1068.     IdleFunc      = NULL;
  1069.     DisplayFunc   = NULL;
  1070.     KeyDownFunc   = NULL;
  1071.     MouseDownFunc = NULL;
  1072.     MouseUpFunc   = NULL;
  1073.     MouseMoveFunc = NULL;
  1074. }
  1075.  
  1076. static void *
  1077. AllocateMemory( size_t Size )
  1078. {
  1079.     return( LocalAlloc( LMEM_FIXED, Size ) );
  1080. }
  1081.  
  1082. static void *
  1083. AllocateZeroedMemory( size_t Size )
  1084. {
  1085.     return( LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, Size ) );
  1086. }
  1087.  
  1088.  
  1089. static void
  1090. FreeMemory( void *Chunk )
  1091. {
  1092.     TKASSERT( NULL!=Chunk );
  1093.  
  1094.     LocalFree( Chunk );
  1095. }
  1096.